Skip to Content

4장 변수

4-1. 변수란 무엇인가? 왜 필요한가?

아래 자바스크립트 코드를 실행하다고 생각해보자.

10 + 20;
  1. 사람이 계산하는 방법
    • 10, 20, +의 의미를 해석할 수 있어야 한다.
    • 10, 20을 먼저 두뇌에 기억한다.
    • 10과 20을 더한 결과인 30을 두뇌에 기억한다.
  2. 컴퓨터가 계산하는 방법 : cpu가 연산하고, memory가 기억한다.
    • 10과 20을 메모리에서 기억한다 ⇒ 메모리란? 데이터를 저장할 수 있는 메모리 셀의 집합체 image.png
      • 메모리 셀 한개의 크기 : 1byte(8bit) ⇒ 컴퓨터는 모든 데이터를 2진수 형태로 저장한다.
      • 메모리 셀마다 고유의 주소가 존재 ⇒ 컴퓨터는 메모리 셀 단위로 데이터를 저장(write) 하거나 읽는다(read).
    • cpu에서 10과 20을 더하는 연산을 수행한다.
    • 연산한 결과인 30을 메모리에서 기억한다. 또다른 메모리 셀에 30이 저장된다 또다른 메모리 셀에 30이 저장된다

그런데, JS에서는 연산 결과인 30을 재사용하기 위해 메모리 셀에 직접 접근할 수 없다.

포인터를 사용하는 C, C++ 등과 다르게 JS는 메모리 주소를 통해 값에 직접 접근하는 것을 허용하지 X

왜냐면, 동일한 컴퓨터에서 동일한 코드를 실행하더라도 값이 저장되는 메모리 주소는 매번 변경되기 때문이다.

⇒ 그래서, 값에 접근하기 위해서는 변수를 이용해서 값에 접근해야 한다.

4-1-1. 변수란?

하나의 값을 저장하기 위해 확보한 메모리 공간, 또는 그 메모리 공간을 식별하기 위해 붙인 이름

→ 즉, 값의 위치의 식별자이다!

변수를 활용하여 코드를 다시 작성해보자.

var result = 10 + 20;
  • 변수명 : 변수 이름 ex) result
  • 변수값 : 변수에 저장된 값 ex) 30
  • 변수 할당 : write ex) result에 30을 저장
  • 변수 참조 : read ex) result에 저장된 30이라는 값을 읽음

image.png

4-2. 식별자

변수 이름, 어떤 값이 저장된 메모리 주소에 붙인 이름

⇒ 즉, 식별자는 변수의 값이 아닌 메모리 주소를 기억

값은 구별하지 못 하고 메모리 주소를 구별한다.

값은 구별하지 못 하고 메모리 주소를 구별한다.

식별자라는 용어는 변수에 국한되지 않고, 함수, 클래스 등 멤모리 상에 존재하는 값에 대한 이름은 모두 식별자

네이밍 규칙을 준수해야 하고, 선언에 의해 JS 엔진이 식별자의 존재를 알 수 있다!

4-3. 변수 선언

변수를 생성하는 것

→ 값을 저장하기 위한 메모리 공간 확보 + 변수 이름과 확보된 메모리 공간의 주소를 연결

4-3-1. 변수 선언 키워드 종류

var, let, const

(let, const는 ES6에 추가된 키워드로, 뒤에서 더 자세히 살펴보자)

var로 변수 선언하기

  1. 선언 단계 : 변수 이름을 등록 → 메모리 공간 확보

    var score;
  2. 초기화 단계 : JS는 암묵적으로 undefined라는 값이 할당되어 초기화된다.

    image.png

var 키워드는 선언 단계와 초기화 단계가 동시에 진행된다.

→ 쓰레기 값이 저장되는 에러로부터 안전하다.

4-3-2. 선언되지 않은 변수에 접근했을 때?

ReferenceError(참조 에러) 발생한다.

→ 해당 이름으로 등록된 변수를 찾지 못 했다는 의미

4-4. 변수 선언의 실행 시점과 변수 호이스팅

변수 호이스팅이란?

변수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 JS 고유의 특징

ex 1) 변수 선언문보다 변수를 참조하는 코드가 앞에 있다.

console.log(score); var score;

선언하기 전에 접근한다면 에러가 발생하지 않을까?

→ 하지만, ReferenceError가 발생하지 않고, undefined가 출력된다.

⇒ JS엔진은 변수 선언이 소스코드에 어디에 있든 다른 코드보다 먼저 실행한다.

ex 2) 변수 선언 앞뒤로 참조하는 코드

console.log(x); // x가 선언된 상태라 undefined가 출력된다 var x = 100; console.log(x); //100이 출력된다

위의 코드는 아래와 같이 JS엔진에 의해 처리된다

var x; //변수 호이스팅, 위로 끌어올려짐 console.log(x); // undefined var x = 100; console.log(x); // 100

var 키워드로 변수를 선언했기에, 선언 단계와 초기화가 동시에 실행된다.

→ undefined 값을 확인할 수 있음

4-4-1. 그럼 만약 let, const 등으로 선언했다면?

letconst는 블록 스코프를 가지며, 블록 내에서만 접근 가능하다

⇒ 변수 선언이 끌어올려지지만, 선언 전에는 접근할 수 없다.

선언 전에 접근을 시도하면 오류가 난다

console.log(b); // ReferenceError: b is not defined let b = 20; console.log(c); // ReferenceError: c is not defined const c = 30;

왜냐하면 letconst는 선언이 호이스팅되지만 초기화는 호이스팅되지 않는다.

4-5. 값의 할당

그렇다면 undefined로 초기화되었던 변수에 어떻게 값을 할당하는가?

할당연산자 =을 사용하여, 오른쪽에 있는 값을 왼쪽으로 할당한다.

var score = 80l

위에서도 언급했듯이,

선언 단계는 호이스팅으로 인해 먼저 이루어지고,

할당 단계는 순차적으로 실행되는 런타임에 실행된다.

console.log(score); // undefined -> 변수 선언은 호이스팅됨 var score; // 1 score = 80; // 2 console.log(score); // 80 -> 런타임 내에 80으로 score의 값이 할당됨

그렇다면 아래 코드는 어떻게 실행될까?

console.log(score); // undefined -> 변수 선언은 호이스팅됨 score = 80; // 2 var score; // 1 console.log(score); // ??

image.png

당연히, 해당 결과도 80으로 출력된다.

4-6. 값의 재할당

4-6-1. 값의 재할당

현재 저장된 값을 버리고 새로운 값을 저장하는 것을 뜻한다.

  • let, var로 선언된 변수 : 값을 재할당할 수 있다.
  • const 로 선언된 변수 : 값을 재할당할 수 없다. → 한 번만 할당할 수 있다

4-6-2. 재할당 과정

image.png

값의 재할당 : score라는 변수의 메모리 주소가 새로운 주소로 바뀌는 것을 뜻한다

→ 사용하지 않는 이전 값이 메모리 주소는 가비지 콜렉터에 의해 자동해제 된다.

→ 다만, 메모리에서 언제 해제되는지 그 시점을 예측할 수는 없다!! (더더욱 개발자가 메모리 주소에 접근하면 X)

4-7. 식별자 네이밍 규칙

변수의 이름을 정하는 것은 아주아주 중요한 일이다.

→ 따라서, 어떻게 이름을 지어야 하는 지에 대한 네이밍 규칙을 준수해야 한다.

  1. 문자, 숫자, 언더스코어(_), 달러기호$ 만 포함할 수 있다.
  2. 숫자로 시작할 수는 없다.
  3. 예약어는 식별자로 사용할 수 없다. 

4-7-1. 네이밍 컨벤션

대표적으로 4가지 유형의 네이밍 컨벤션이 있다

  • 카멜 케이스 : 변수, 함수의 이름 let devoceanYoung; 소문자대문자
  • 파스칼 케이스 : 생성자 함수, 클래스 이름 let DevoceanYoung; 대문자대문자
  • 스네이크 케이스 let devocean_young; 소문자_소문자
  • 헝가리언 케이스 let strDevoceanYoung; 타입대문자대문자
Last updated on